﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 路径扫描2._0
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            StartPosition = FormStartPosition.CenterScreen;
            button2.Enabled = false;//默认加载是被禁用状态
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        public int y = 0;//统计正确总数
        public int u = 0;//统计错误总数
        public int z = 0;//统计请求总数
        public int s = 0;//请求延迟
        public string s9;//服务器地址
        public int s8;
        public string s7;//密码
        public string s6;//账号
        private void 代理设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //可配置代理去进行扫描
            ProxxScan proxx = new ProxxScan();
            proxx.StartPosition = FormStartPosition.CenterScreen;
            proxx.ShowDialog();
        }
        public Thread th;
        public Thread tr;
        private void button1_Click(object sender, EventArgs e)
        {
            if(comboBox2.Text == "多线程")
            {
                if (textBox1.Text == string.Empty)
                {
                    //Console.WriteLine("创建时间：" + DateTime.Now + "   ------   " + "扫描地址不能为空..." + "\r\n");
                    LogError("创建时间：" + DateTime.Now + "   ------   " + "扫描地址不能为空..." + "\r\n");
                    return;
                }
                else
                {
                    //能成功执行的情况下，禁用按钮
                    this.timer1.Enabled = true;
                    this.timer1.Interval = 100;
                    this.timer1.Start();
                    button1.Enabled = false;
                    button2.Enabled = true;
                    LogError("创建时间：" + DateTime.Now + "   ------   " + "正在创建线程..." + "\r\n");
                    LogError("创建时间：" + DateTime.Now + "   ------   " + "获取到使用代理扫描..." + "\r\n");
                }
                if (comboBox1.Text == "否")
                {
                    //不进行代理扫描
                    th = new Thread(FscanWeb);
                    th.IsBackground = false;
                    th.Start();
                }
                else
                {
                    //进行代理扫描
                    th = new Thread(ProxxScan);
                    th.IsBackground = false;
                    th.Start();
                }
            }
            else
            {
                if (textBox1.Text == string.Empty)
                {
                    //Console.WriteLine("创建时间：" + DateTime.Now + "   ------   " + "扫描地址不能为空..." + "\r\n");
                    LogError("创建时间：" + DateTime.Now + "   ------   " + "扫描地址不能为空..." + "\r\n");
                    return;
                }
                else
                {
                    //能成功执行的情况下，禁用按钮
                    this.timer1.Enabled = true;
                    this.timer1.Interval = 100;
                    this.timer1.Start();
                    button1.Enabled = false;
                    button2.Enabled = true;
                    LogError("创建时间：" + DateTime.Now + "   ------   " + "正在创建自定义线程..." + "\r\n");
                    LogError("创建时间：" + DateTime.Now + "   ------   " + "获取到使用代理扫描..." + "\r\n");
                }
                if (comboBox1.Text == "否")
                {
                    //for (int i = 0; i < amountThread; i++)
                    //{
                    //    Thread trd = new Thread(new ThreadStart(FscanWeb1));
                    //    trd.Name = "线程：" + i;
                    //    trd.Start();
                    //}
                    //int threadsr = Convert.ToInt32(comboBox2.Text);
                    //for (int i = 0; i <= threadsr; i++)
                    //{
                    //    //ThreadPool.QueueUserWorkItem(new WaitCallback(StartAsync), i.ToString());
                    //    tr = new Thread(new ParameterizedThreadStart(FscanWeb1));
                    //    tr.Start(i);
                    //}
                    MessageBox.Show("暂不开放");
                    return;
                    //不进行代理扫描
                    //int numxc = Convert.ToInt32(comboBox2.Text);
                    ////Thread jk = new Thread(FscanWeb1, numxc);
                    ////jk.Start();
                    ////ThreadPool.SetMaxThreads(16, 16);// 设置线程池最大线程数量
                    ////ThreadPool.SetMinThreads(Convert.ToInt32(comboBox2.Text), Convert.ToInt32(comboBox2.Text));
                    //ThreadPool.SetMaxThreads(50, 50);//最大
                    ////ThreadPool.SetMinThreads(50, 50);//最小
                    //for (int i = 0; i < numxc; i++)
                    //{
                    //    ThreadPool.QueueUserWorkItem(new WaitCallback(FscanWeb1), i.ToString());//创建线程去执行CtuIko的公共方法
                    //    //Thread jk = new Thread(FscanWeb1,Convert.ToInt32(i.ToString()));
                    //    //jk.Start();
                    //    //FscanWeb();
                    //}
                }
                else
                {
                    //进行代理扫描
                    th = new Thread(ProxxScan);
                    th.IsBackground = false;
                    th.Start();
                } 
            }
        }
        /// <summary>
        /// 非代理扫描
        /// </summary>
        private static int poolFlag = 0;//标记 
        public const int amountThread = 30;//线程总量 
        private const int maxThread = 3;//可执行线程最大数量 
        private static Mutex muxConsole = new Mutex();
        public void FscanWeb()
        {
            //设置扫描状态
            toolStripStatusLabel3.Text = "扫描中";
            //非IP代理的扫描
            //Console.WriteLine("创建时间：" + DateTime.Now + "   ------   " + "正在创建非代理扫描线程..." + "\r\n");
            LogMessage("创建时间：" + DateTime.Now + "   ------   " + "正在创建非代理扫描线程..." + "\r\n");
            //创建请求
            string url = textBox1.Text;
            string path = @"WebDic\dic.txt";
            using (StreamReader sr = new StreamReader(path, Encoding.Default))
            {
                string str = sr.ReadToEnd();
                try
                {
                    if (!string.IsNullOrEmpty(str))
                    {
                        string[] strs = str.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < strs.Length; i++)
                        {
                            try
                            {
                                int sm = Convert.ToInt32(textBox4.Text);
                                s = sm * 1000;
                                System.Threading.Thread.Sleep(Convert.ToInt32(s));//请求延迟的方式
                                HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(url + strs[i]);
                                HttpWebResponse response = (HttpWebResponse)httpReq.GetResponse();
                                httpReq.Timeout = Convert.ToInt32(textBox3.Text);
                                httpReq.Headers.Add("Accept-Encoding", "Gzip");//速度会更快一些
                                var v = response.StatusCode;//初始化状态
                                                            //表示能访问的情况下
                                if (v == HttpStatusCode.OK)
                                {
                                    Console.WriteLine("扫描时间：" + DateTime.Now + "   ------   " + url + str[i] + "   ---   " + "状态：" + HttpStatusCode.OK);
                                    //LogMessage("扫描时间：" + DateTime.Now + "   ------   " + url + strs[i] + "   ---   " + "状态：" + HttpStatusCode.OK + "\r\n");
                                    LogMessages("扫描时间：" + DateTime.Now + "   ------   " + url + strs[i] + "   ---   " + "状态：" + HttpStatusCode.OK + "\r\n");
                                    y++;
                                    toolStripStatusLabel7.Text = y.ToString();
                                    //dataGridView1.Rows.Add(url + strs[i], HttpStatusCode.OK);
                                }
                                //不进行生效 直接输出到 catch 中
                                if (v == HttpStatusCode.NotFound)
                                {
                                    LogError("扫描时间：" + DateTime.Now + "   ------   " + url + str.ToString() + "   ---   " + "状态：" + HttpStatusCode.NotFound);
                                }
                                httpReq.Abort();
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("创建时间：" + DateTime.Now + "   ------   " + "\r\n" + ex);
                                LogError("扫描时间：" + DateTime.Now + "   ------   " + url + strs[i] + "   ---   " + "状态：无法访问" + "\r\n");
                                u++;
                                toolStripStatusLabel9.Text = u.ToString();
                            }
                            z++;
                            toolStripStatusLabel11.Text = z.ToString();
                        }
                    }
                }
                catch(Exception ex)
                {
                    LogMessage(ex.ToString());
                }
            }
            //自动结束后的操作
            this.timer1.Enabled = false;
            this.timer1.Stop();
            toolStripStatusLabel5.Text = "0";
            toolStripStatusLabel3.Text = "扫描结束";
            button1.Enabled = true;
            button2.Enabled = false;
        }
        /// <summary>
        /// 代理扫描
        /// </summary>
        /// 
        static Object obj = new object();
        public void FscanWeb1()
        {
            //设置扫描状态
            muxConsole.WaitOne();
            Interlocked.Increment(ref poolFlag);
            if(poolFlag != maxThread)
            {
                muxConsole.ReleaseMutex();
            }
            toolStripStatusLabel3.Text = "扫描中";
            //非IP代理的扫描
            //Console.WriteLine("创建时间：" + DateTime.Now + "   ------   " + "正在创建非代理扫描线程..." + "\r\n");
            LogMessage("创建时间：" + DateTime.Now + "   ------   " + "正在创建非代理扫描线程..." + "\r\n");
            //创建请求
            string url = textBox1.Text;
            string path = @"WebDic\dic.txt";
            using (StreamReader sr = new StreamReader(path, Encoding.Default))
            {
                string str = sr.ReadToEnd();
                try
                {
                    if (!string.IsNullOrEmpty(str))
                    {
                        string[] strs = str.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < strs.Length; i++)
                        {
                            try
                            {
                                int sm = Convert.ToInt32(textBox4.Text);
                                s = sm * 1000;
                                System.Threading.Thread.Sleep(Convert.ToInt32(s));//请求延迟的方式
                                HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(url + strs[i]);
                                HttpWebResponse response = (HttpWebResponse)httpReq.GetResponse();
                                httpReq.Timeout = Convert.ToInt32(textBox3.Text);
                                httpReq.Headers.Add("Accept-Encoding", "Gzip");//速度会更快一些
                                var v = response.StatusCode;//初始化状态
                                                            //表示能访问的情况下
                                if (v == HttpStatusCode.OK)
                                {
                                    Console.WriteLine("扫描时间：" + DateTime.Now + "   ------   " + url + str[i] + "   ---   " + "状态：" + HttpStatusCode.OK);
                                    //LogMessage("扫描时间：" + DateTime.Now + "   ------   " + url + strs[i] + "   ---   " + "状态：" + HttpStatusCode.OK + "\r\n");
                                    LogMessages("扫描时间：" + DateTime.Now + "   ------   " + url + strs[i] + "   ---   " + "状态：" + HttpStatusCode.OK + "\r\n");
                                    y++;
                                    toolStripStatusLabel7.Text = y.ToString();
                                    //dataGridView1.Rows.Add(url + strs[i], HttpStatusCode.OK);
                                }
                                //不进行生效 直接输出到 catch 中
                                if (v == HttpStatusCode.NotFound)
                                {
                                    LogError("扫描时间：" + DateTime.Now + "   ------   " + url + str.ToString() + "   ---   " + "状态：" + HttpStatusCode.NotFound);
                                }
                                httpReq.Abort();
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine("创建时间：" + DateTime.Now + "   ------   " + "\r\n" + ex);
                                LogError("扫描时间：" + DateTime.Now + "   ------   " + url + strs[i] + "   ---   " + "状态：无法访问" + "\r\n");
                                u++;
                                toolStripStatusLabel9.Text = u.ToString();
                            }
                            z++;
                            toolStripStatusLabel11.Text = z.ToString();
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogMessage(ex.ToString());
                }
            }
            Interlocked.Decrement(ref poolFlag);
            //自动结束后的操作
            this.timer1.Enabled = false;
            this.timer1.Stop();
            toolStripStatusLabel5.Text = "0";
            toolStripStatusLabel3.Text = "扫描结束";
            button1.Enabled = true;
            button2.Enabled = false;
        }
        public void ProxxScan()
        {
            MessageBox.Show("请在自行在代理设置中验证代理的可用性，扫描时不会对其进行检查");
            //设置扫描状态
            toolStripStatusLabel3.Text = "扫描中";
            //读取数据库代理配置、
            string path1 = @"data source=WebScanDb\Sec_Webscan.db";
            SQLiteConnection dataConn = new SQLiteConnection(path1);
            dataConn.Open();
            if (dataConn.State == ConnectionState.Open)
            {
                DataSet ds = new DataSet();
                string sql = "SELECT service, port, user, pass FROM sec_Webscan_Setting";
                SQLiteCommand command = new SQLiteCommand(sql, dataConn);
                command.ExecuteNonQuery();
                SQLiteDataAdapter mAdapt = new SQLiteDataAdapter(command);
                mAdapt.Fill(ds);
                var ss = mAdapt.ToString();
                //判断是否进行执行 如果执行之后就进行打印
                if (ss.Length != 1)
                {
                    s9 = ds.Tables[0].Rows[0]["service"].ToString();
                    s8 = Convert.ToInt32(ds.Tables[0].Rows[0]["port"].ToString());//int类型
                    s7 = ds.Tables[0].Rows[0]["pass"].ToString();
                    s6 = ds.Tables[0].Rows[0]["user"].ToString();
                    Console.WriteLine(DateTime.Now + "   ------   " + "代理配置加载成功" + "\r\n");
                    dataConn.Close();
                }
                else
                {
                    LogError("创建时间：" + DateTime.Now + "   ------   " + "   ---   " + "代理加载失败" + "\r\n");
                    return;
                }
            }
            //Console.WriteLine("创建时间：" + DateTime.Now + "   ------   " + "正在创建非代理扫描线程..." + "\r\n");
            LogMessage("创建时间：" + DateTime.Now + "   ------   " + "正在创建代理扫描线程..." + "\r\n");
            //创建请求
            string url = textBox1.Text;
            string path = @"WebDic\dic.txt";
            using (StreamReader sr = new StreamReader(path, Encoding.Default))
            {
                string str = sr.ReadToEnd();
                if (!string.IsNullOrEmpty(str))
                {
                    string[] strs = str.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < strs.Length; i++)
                    {
                        try
                        {
                            int sm = Convert.ToInt32(textBox4.Text);
                            s = sm * 1000;
                            System.Threading.Thread.Sleep(Convert.ToInt32(s));//请求延迟的方式
                            HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(url + strs[i]);
                            httpReq.Timeout = Convert.ToInt32(textBox3.Text);
                            httpReq.Headers.Add("Accept-Encoding", "Gzip");//速度会更快一些
                            //代理服务器
                            string ip = s9;
                            int port = s8;
                            //代理账号密码
                            string user = s6;//账号
                            string pass = s7;
                            //设置代理
                            WebProxy proxy = new WebProxy();
                            proxy.Address = new Uri(String.Format("http://{0}:{1}", ip, port));
                            proxy.Credentials = new NetworkCredential(user, pass);
                            httpReq.Proxy = proxy;
                            //发起请求
                            HttpWebResponse response = (HttpWebResponse)httpReq.GetResponse();
                            var v = response.StatusCode;//初始化状态
                            //表示能访问的情况下
                            if (v == HttpStatusCode.OK)
                            {
                                Console.WriteLine("扫描时间：" + DateTime.Now + "   ------   " + url + str[i] + "   ---   " + "状态：" + HttpStatusCode.OK);
                                //LogMessage("扫描时间：" + DateTime.Now + "   ------   " + url + strs[i] + "   ---   " + "状态：" + HttpStatusCode.OK + "\r\n");
                                LogMessages("扫描时间：" + DateTime.Now + "   ------   " + url + strs[i] + "   ---   " + "状态：" + HttpStatusCode.OK + "\r\n");
                                y++;
                                toolStripStatusLabel7.Text = y.ToString();
                                //dataGridView1.Rows.Add(url + strs[i], HttpStatusCode.OK);
                            }
                            //不进行生效 直接输出到 catch 中
                            if (v == HttpStatusCode.NotFound)
                            {
                                LogError("扫描时间：" + DateTime.Now + "   ------   " + url + str.ToString() + "   ---   " + "状态：" + HttpStatusCode.NotFound);
                            }
                            httpReq.Abort();
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("创建时间：" + DateTime.Now + "   ------   " + "\r\n" + ex);
                            LogError("扫描时间：" + DateTime.Now + "   ------   " + url + strs[i] + "   ---   " + "状态：无法访问" + "\r\n");
                            u++;
                            toolStripStatusLabel9.Text = u.ToString();
                        }
                        z++;
                        toolStripStatusLabel11.Text = z.ToString();
                    }
                }
            }
            //自动结束后的操作
            toolStripStatusLabel3.Text = "扫描结束";
            button1.Enabled = true;
            button2.Enabled = false;

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            toolStripStatusLabel5.Text = "0";
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            //设置richtextbox 默认显示最新的一条数据
            if (richTextBox1.Text.Length > 0)
            {
                richTextBox1.SelectionStart = richTextBox1.Text.Length;
                //richTextBox1.SelectionStart = Convert.ToInt32(richTextBox1.Text.Remove(richTextBox1.Text.Length - 1));
                richTextBox1.ScrollToCaret();
            }
            //richTextBox1.SelectionStart = richTextBox1.Text.Length;
            //richTextBox1.ScrollToCaret();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //线程终止
            if(th != null&&th.IsAlive)
            {
                th.Abort();
                this.timer1.Enabled = false;
                this.timer1.Stop();
                LogError("创建时间：" + DateTime.Now + "   ------   " + "扫描线程已结束..." + "\r\n");
                button1.Enabled = true;
                button2.Enabled = false;
                //设置扫描状态
                toolStripStatusLabel3.Text = "扫描结束";
                toolStripStatusLabel5.Text = "0";
            }
            if(tr != null && tr.IsAlive)
            {
                tr.Abort();
                this.timer1.Enabled = false;
                this.timer1.Stop();
                LogError("创建时间：" + DateTime.Now + "   ------   " + "扫描线程已结束..." + "\r\n");
                button1.Enabled = true;
                button2.Enabled = false;
                //设置扫描状态
                toolStripStatusLabel3.Text = "扫描结束";
                toolStripStatusLabel5.Text = "0";
            }
        }

        private void richTextBox2_TextChanged(object sender, EventArgs e)
        {
            if (richTextBox2.Text.Length > 0)
            {
                richTextBox2.SelectionStart = richTextBox2.Text.Length;
                //richTextBox1.SelectionStart = Convert.ToInt32(richTextBox1.Text.Remove(richTextBox1.Text.Length - 1));
                richTextBox2.ScrollToCaret();
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //关闭窗体时发生时，判断线城市是否结束，如果在线程没有关闭并强行结束线程的情况下，就会导致结束后再次启动时发生错误
            //最好的方法是必须的结束创建的线程，否则就不能结束
            if (th != null && th.IsAlive)
            {
                DialogResult Result = MessageBox.Show("请终止扫描线程后进行关闭，强制关闭程序将引发错误", "操作警告", MessageBoxButtons.OKCancel);
                if (Result == DialogResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
        }
        /// <summary>
        /// 对输出颜色进行封装 rictextbox1
        /// </summary>
        /// <param name="color"></param>
        /// <param name="text"></param>
        public delegate void LogAppendDelegate(Color color, string text);
        public void LogAppend(Color color, string text)
        {
            //richTextBox1.AppendText("\r\n");
            richTextBox1.SelectionColor = color;
            richTextBox1.AppendText(text);
        }
        /// red
        public void LogError(string text)
        {
            LogAppendDelegate la = new LogAppendDelegate(LogAppend);
            richTextBox1.Invoke(la, Color.Red, text);
        }
        /// 警告
        public void LogWarning(string text)
        {
            LogAppendDelegate la = new LogAppendDelegate(LogAppend);
            richTextBox1.Invoke(la, Color.Violet, text);
        }
        /// 绿色
        public void LogMessage(string text)
        {
            LogAppendDelegate la = new LogAppendDelegate(LogAppend);
            richTextBox1.Invoke(la, Color.Green, text);
        }
        /// <summary>
        /// 对输出颜色进行封装 rictextbox2
        /// </summary>
        /// <param name="color"></param>
        /// <param name="text"></param>
        public delegate void LogAppendDelegate1(Color color, string text);
        public void LogAppends(Color color, string text)
        {
            //richTextBox1.AppendText("\r\n");
            richTextBox2.SelectionColor = color;
            richTextBox2.AppendText(text);
        }
        /// 绿色
        public void LogMessages(string text)
        {
            LogAppendDelegate la = new LogAppendDelegate(LogAppends);
            richTextBox2.Invoke(la, Color.Green, text);
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            //获取线程数
            Process myProcess = Process.GetCurrentProcess();//获取该进程
            ProcessThreadCollection PTC = myProcess.Threads;//获取其关联的线程，包括主线程
            int num = PTC.Count;//获取线程数量
            toolStripStatusLabel5.Text = num.ToString();
        }

        private void 扫描帮助ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SecHelp sec = new SecHelp();
            sec.StartPosition = FormStartPosition.CenterScreen;
            sec.ShowDialog();
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            toolStripStatusLabel1.Text = System.DateTime.Now.ToString("F");
        }

        private void 创建扫描ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form1 form = new Form1();
            form.StartPosition = FormStartPosition.CenterScreen;
            form.Show();
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}
